package com.zhonghan.recharge.controller;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.zhonghan.common.bean.Result;
import com.zhonghan.common.enums.ResultStatus;
import com.zhonghan.common.utils.StringUtils;
import com.zhonghan.common.utils.TimerDifferent;
import com.zhonghan.common.variable.GlobalVariable;
import com.zhonghan.common.wechat.api.SnsApi;
import com.zhonghan.common.wechat.bean.sns.SnsToken;
import com.zhonghan.common.wechat.bean.user.SnsUserInfo;
import com.zhonghan.recharge.pojo.Activity;
import com.zhonghan.recharge.pojo.GascardInfo;
import com.zhonghan.recharge.pojo.ZhFillCard;
import com.zhonghan.recharge.pojo.ZhGascardOrder;
import com.zhonghan.recharge.service.BmItemService;
import com.zhonghan.recharge.service.GascardInfoService;
import com.zhonghan.recharge.service.IRechargeServcie;
import com.zhonghan.recharge.service.JiSuRechargeService;
import com.zhonghan.recharge.service.ZhFillCardService;
import com.zhonghan.recharge.service.ZhGascardOrderService;

/**
 * 充值控制层
 * @author zhangceven
 *
 */
@RequestMapping("/recharge")
@Controller
public class RechargeController {
	
	
	private static final Logger logger = LogManager.getLogger(RechargeController.class);
	
	@Value("${wechat.APPID}")
	private String APPID;
	
	@Value("${wechat.APPSECRET}")
	private String APPSECRET;
	@Value("${wechat.DOMAIN}")
	private String DOMAIN;
	
	@Value("${recharge_status}")
	private String recharge_status;
	
	@Value("test_fill_cards")
	private String test_fill_cards;
	
	@Value("${oilRecharge.imgUrl:}" )
	private String imgUrl;
	
	@Autowired
	private ZhFillCardService zhFileCardService;
	
	@Autowired
	private ZhGascardOrderService zhGascardOrderService;
	
	@Autowired
	private BmItemService bmItemService;
	
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	
	@Autowired
	private IRechargeServcie rechargeService;
	
	@Autowired
	private GascardInfoService casCardInfoService;
	
	@RequestMapping(value="/oil/change/recharge", method=RequestMethod.GET)
	@ResponseBody
	public String changeRecharge(String rechargeStatus) throws Exception {
		
		//return "RechargeOilCard";
		//return "serverwh";  //系统维护
		recharge_status = rechargeStatus;
		
		return recharge_status;
		
	}
	
	@RequestMapping(value="/oil/change/fillCards", method=RequestMethod.GET)
	@ResponseBody
	public String changeFillCards(String cards) throws Exception {
		
		//return "RechargeOilCard";
		//return "serverwh";  //系统维护
		test_fill_cards = cards;
		
		return test_fill_cards;
		
	}
	
	/**
	 * 跳转到油卡充值页面
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/oil/card", method=RequestMethod.GET)
	public String showOilRecharge(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
		//接收微信回调回来的code
		String code = request.getParameter("code");
		
		if(StringUtils.isEmpty(code)){
			// 第一步: 生成网页授权url
			String redirect_uri = DOMAIN + "/recharge/oil/card";
			String connectOauth2Authorize = SnsApi.connectOauth2Authorize(APPID, redirect_uri , true, "STATE" );
			
			response.sendRedirect(connectOauth2Authorize);
			logger.info("微信网页授权");
		}else{
			// 第二步: 通过 code 换取网页授权access_token
			String access_token = (String) request.getSession().getAttribute("ACCESS_TOKEN");
			SnsToken snsToken = SnsApi.oauth2AccessToken(APPID, APPSECRET, code);
			if(StringUtils.isEmpty(access_token)){
				access_token = snsToken.getAccess_token();
				HttpSession session = request.getSession();
				session.setAttribute("ACCESS_TOKEN", access_token);
				session.setMaxInactiveInterval(7200);
			}

			
			String openid = snsToken.getOpenid();
			
			logger.info("OpenID: " + openid);
			//System.out.println("OpenID: " + openid);
			
			SnsUserInfo snsUserInfo = SnsApi.snsUserinfo(access_token, openid, "zh_CN");
			
			logger.info(snsUserInfo);
			//System.out.println(snsUserinfo);
			
			model.addAttribute("SnsUserInfo",snsUserInfo);
			model.addAttribute("RechargeStates", recharge_status);
			
			if(StringUtils.isNotEmpty(imgUrl)){
				model.addAttribute("ImgUrl", imgUrl);
			}
			Activity activity = GlobalVariable.activity;
			if(activity != null){
				model.addAttribute("Activity", activity);
			}
			return "RechargeOilCard";
			
			/*if("1".equals(recharge_status)){
				
			}else{
				return "serverwh";  //系统维护
			}*/
		}
		return null;
		
		// 如果code为空,则打开微信授权页面
		/*if(StringUtils.isEmpty(code)){
			// 第一步: 生成网页授权url
			String redirect_uri = DOMAIN + "/recharge/oil/card";
			String state = "STATE";
			String connectOauth2Authorize = SnsApi.connectOauth2Authorize(APPID, redirect_uri , true, state );
			
			response.sendRedirect(connectOauth2Authorize);
			logger.info("微信网页授权" + code);
			return null;
		}*/
		
		
		//设置某些卡可以通过
		
		/**/
		//return "RechargeOilCard";
		//return "serverwh";  //系统维护
	}
	
	
	@Autowired
	private JiSuRechargeService jiSuRechargeService;
	
	/**
	 * 油卡充值操作
	 * @param request
	 * @param response
	 * @param name
	 * @param telephone
	 * @param rechargeNo  充值卡号
	 * @param password    充值卡密码
	 * @return
	 */
	@RequestMapping(value="/oil/card",method=RequestMethod.POST)
	@ResponseBody
	public Result oilCharge(String gasnumber, String gasname, String gasphone, String gastype, String recardno,
			String password,String openid, HttpServletRequest request,Model model,HttpServletResponse response) {
		
		logger.info("充油开始："+gasname+" "+gasnumber+" "+gasphone+" "+gastype+" "+recardno);
		gasnumber.trim();
		gasname.trim();
		gasphone.trim();
		gastype.trim();
		recardno.trim();
		password.trim();
		openid.trim();
		
		Result result = new Result();
		if(!gasnumber.equals("") && !gasname.equals("") && !gasphone.equals("") 
				&& !gastype.equals("") && !recardno.equals("") && !password.equals("")) {
			
			//String openid="api";
			// 判断
			logger.info("中石化100充值卡，从此路过....");
			
			 //走极速  接口
			try {
				if(getGasNumberUse(gasnumber)) {
					//继续充值
					if("1".equals(recharge_status)){
						result = jiSuRechargeService.insertOilRechargeService(gasnumber, gasname, gasphone, gastype, recardno, password, openid);
						
					}else if(test_fill_cards.indexOf(recardno) != -1){
						result = jiSuRechargeService.insertOilRechargeService(gasnumber, gasname, gasphone, gastype, recardno, password, openid);
					}else if("2".equals(recharge_status)){
						result.setCode("2");
						result.setMsg("系统开放时间每天是9:00 - 18:00");
						logger.info("系统开放时间是9:00 - 18:00.");
					}else{
						result.setCode("0");
						result.setMsg("系统正在维护中....");
						logger.info("系统正在维护中....");
					}
					
					
					//result = rechargeService.insertOilRechargeService(gasnumber, gasname, gasphone, gastype, recardno, password, openid);
				}else {
					result.setCode("0");
					result.setMsg("一张油卡充值一天只能充5次");
					logger.info("油卡一天超过5次："+gasnumber+" "+gasname+" "+gastype);
					return result;
				}
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				// TODO Auto-generated catch block
				String message = e.getMessage();
				result = JSON.parseObject(message, Result.class);
				logger.info("..........controller,极速 充油失败"+result.getCode()+" "+result.getMsg());
			}
			/*ZhFillCard zfc = new ZhFillCard();
			zfc.setSequence(recardno);
			zfc.setPassword(password);
			List<ZhFillCard> zfcList = zhFileCardService.selectZhFillCardByObj(zfc );
			// 查询到充值卡信息,保存订单
			zfc = zfcList.get(0);
			if(zfc.getFacePrice()==100 && "sinopec".equals(gastype)) {
				logger.info("中石化100充值卡，从此路过....");
				 //走极速  接口
				 
				try {
					result = jiSuRechargeService.insertOilRechargeService(gasnumber, gasname, gasphone, gastype, recardno, password, openid);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					// TODO Auto-generated catch block
					String message = e.getMessage();
					result = JSON.parseObject(message, Result.class);
					logger.info("..........controller,极速 充油失败"+result.getCode()+" "+result.getMsg());
				}
			}else {
				
				try {
					result = rechargeService.insertOilRechargeService(gasnumber, gasname, gasphone, gastype, recardno, password, openid);
					//如果订单成功，返回订单详细
					return result;
				}catch (Exception e) {
					// TODO Auto-generated catch block
					String message = e.getMessage();
					result = JSON.parseObject(message, Result.class);
					logger.info("..........controller,充油失败"+result.getCode()+" "+result.getMsg());
					result.setCode("0");
					result.setMsg("油卡充值失败!");
				}
			}*/
			
		}else {
			result.setCode("0");
			result.setMsg("参数不全");
			
		}
		//跳转到失败页面，
		
		return result;
		
	}
	/**
	 * 
	 * @param recardno
	 * @param password
	 * @param openid
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/findcardinfo",method=RequestMethod.POST)
	@ResponseBody
	public Result oilCharge(String recardno,
			String password, HttpServletRequest request) {
		
		recardno.trim();
		password.trim();
		//获取输入的数据	,获取油卡卡号和姓名，手机号，中石油，中石化。
		Result result = new Result();
		
		try {
		logger.info("查询的充值卡是："+recardno);
		// 判断
		ZhFillCard zfc = new ZhFillCard();
		zfc.setSequence(recardno);
		zfc.setPassword(password);
		List<ZhFillCard> zfcList = zhFileCardService.selectZhFillCardByObj(zfc );
		logger.info("查询到充值卡："+zfcList.size());
		if(zfcList!=null && zfcList.size()>0){
			// 查询到充值卡信息,保存订单
			zfc = zfcList.get(0);
			if(zfc.getStatus()==2){
				// 卡已消费
				result.setCode("2");
				result.setMsg("对不起,您输入的卡号已经被消费");
				return result;
			}else if(zfc.getStatus()==-1){
				// 卡已消费
				result.setCode("0");
				result.setMsg("对不起,您输入的卡号未激活");
				logger.info("充值卡未激活.....");
				return result;
			}
			//面额
			result.setCode("1");
			result.setData(zfc.getFacePrice());
			return result;
		}else{
			// 没有查询到油卡信息
			result.setCode("0");
			result.setMsg("充值卡序列号或密码不正确,请检查好后重新输入");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			result.setCode(ResultStatus.BUSYNESS.getCode());
			result.setMsg(ResultStatus.BUSYNESS.getDescription());
		}
		
		return result;
	}
	
	public boolean getGasNumberUse(String gasnumber) throws ParseException {
		GascardInfo obj = new GascardInfo();
		obj.setCardNo(gasnumber);
		// 保存用户油卡信息到数据库
		
		GascardInfo gi = casCardInfoService.selectGascardInfoByObj(obj );
		
		Integer useNum = gi.getUseNum();
		String oldUseTime = gi.getUseTime();
		int days = 2;
		if(oldUseTime != null) {
			days = TimerDifferent.differentDaysByMillisecond(sdf.parse(oldUseTime), new Date());
		}
		//判断该油卡最近使用时间是否 是当天
		if(days >=1) {
			gi.setUseNum(1);
		}
		if(days <1 && useNum < 5 ) {
			gi.setUseNum(gi.getUseNum() + 1);
		}
		if(days < 1 && useNum >= 5) {
			return false;
		}
		return true;
	}
	
	/**
	 * * 查询油卡信息
	 * @param gasnumber 油卡卡号
	 * @param gasname 油卡持有人
	 * @param gastype 油卡类型 中石化sinopec,中石油cnpc
	 * @param openid
	 * @param gasphone
	 * @return
	 */
	@RequestMapping("/oil/get")
	@ResponseBody
	public Result oilCardPrice(String gasnumber,String gasname,String gastype, String openid, String gasphone) {
		
		logger.info(gasname+" "+gasnumber+" "+gasphone+" "+gastype);
		Result result = new Result();
		try {
			boolean isGas = true;
			if(isGas) {
				GascardInfo obj = new GascardInfo();
				obj.setCardNo(gasnumber);
				// 保存用户油卡信息到数据库
				
				GascardInfo gi = casCardInfoService.selectGascardInfoByObj(obj );
				
				if(gi == null){
					GascardInfo value = new GascardInfo();
					value.setCratetime(sdf.format(new Date())); // 创建时间
					value.setCardState("1");// 设置油卡状态(后期要改)
					value.setCardNo(gasnumber);
					value.setOpenid(openid);
					value.setCardName(gasname);
					value.setCardOperatorType(gastype);
					value.setUseNum(0);
					value.setCardPhone(gasphone);
					value.setUseTime(sdf.format(new Date()));
					int rs = casCardInfoService.insertNonEmptyGascardInfo(value);
					logger.info("查询到油卡,并保存油卡信息到数据库："+value.getCardNo()+";"+rs);
					result.setCode("1");
					result.setMsg("添加成功");
				}else{
					/*Integer useNum = gi.getUseNum();
					String oldUseTime = gi.getUseTime();
					int days = 2;
					if(oldUseTime != null) {
						days = TimerDifferent.differentDaysByMillisecond(sdf.parse(oldUseTime), new Date());
					}
					//判断该油卡最近使用时间是否 是当天
					if(days >=1) {
						gi.setUseNum(1);
					}
					if(days <1 && useNum < 5 ) {
						gi.setUseNum(gi.getUseNum() + 1);
					}
					if(days < 1 && useNum >= 5) {
						result.setCode("0");
						result.setMsg("一张油卡充值一天只能充5次");
						logger.info("油卡一天超过5次："+gasnumber+" "+gasname+" "+gastype);
						return result;
					}
				
					gi.setUseTime(sdf.format(new Date()));
					gi.setCardName(gasname);
					casCardInfoService.updateNonEmptyGascardInfoById(gi);*/
					logger.info("查询到油卡,累加使用次数:"+gi.getUseNum());
					result.setCode("1");
					result.setMsg("查询成功");
				}
			}else {
				result.setCode("0");
				result.setMsg("查询失败");
			}
		}catch(Exception e) {
			logger.info("oil/get==="+e.getMessage());
		}
		//判断油卡信息是否正确
//		return "$50";

		return result;
	}
	/**
	 * MD5加密
	 * @param str
	 * @return
	 */
	public static String getMD5Str(String str) {
		MessageDigest messageDigest = null;
		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			
		}
		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}

		return md5StrBuff.toString();
	}
	/**
	 * 斑马充油 推送请求
	 * @param request
	 * @param response
	 * @return
	 */
	private static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
	
	@RequestMapping(value = "/oil/callback", method = {RequestMethod.POST, RequestMethod.GET})
	@ResponseBody
	public String postCallback(HttpServletRequest request, HttpServletResponse response) {
	    // 从request获取参数
		/**
		 * 所有的参数:
				user_id:A1884513
				sign:A9DBB8E3DB8C827FA958767A677E52AF4348085D
				recharge_state:9
				outer_tid:72dde5ba9e364270a8f408df056ccb7d
				tid:S1801178203844
				timestamp:2018-01-17 15:23:05
		 */
	   // Enumeration keys = request.getParameterNames();
	    logger.info("斑马回调所有的参数:");
	    /*while (keys.hasMoreElements()) {
	        String key = (String)keys.nextElement();
	        String value = request.getParameter(key);
	        logger.info(key + ":" + value);
	    }*/
	 // 启动线程处理消息
	    String item_id = request.getParameter("user_id");
	    final String myOrderId = request.getParameter("outer_tid");
	    final String recharge_state = request.getParameter("recharge_state");
	    final String timestamp = request.getParameter("timestamp");
	    logger.info(item_id+" "+myOrderId+" "+recharge_state+" "+timestamp);
    	executorService.submit(new Runnable() {
            @Override
            public void run() {
            	try {
        		   //还原操作
        		    zhGascardOrderService.updateRechargeStateByOrderNoByCallBack(myOrderId, recharge_state,timestamp);
        		    //
        		    // 给服务器响应success字符串（收到请求后5秒内），否则将每一分钟发送回调信息一次，共发送4次。
        		    // 如果4次还未返回success，则服务器丢弃消息
        		    
        		} catch (Exception e) {
        			// TODO: handle exception
        		}
            }
        });
        
	    
	    
	    
	    // 验证签名，其他业务逻辑
	    
	    // 给服务器响应success字符串（收到请求后5秒内），否则将每一分钟发送回调信息一次，共发送4次。
	    // 如果4次还未返回success，则服务器丢弃消息
	    return "success";
	}
	
	/**
	 * 查询订单状态
	 * @param request
	 * @param orderNo
	 * @return
	 */
	@RequestMapping(value="/oil/card/result", method=RequestMethod.GET)
	public String oilRechargeResult(HttpServletRequest request,String orderNo,Model model){
		
		if(StringUtils.isNotEmpty(orderNo)){
			ZhGascardOrder zgo = new ZhGascardOrder();
			zgo.setOrderNo(orderNo);
			List<ZhGascardOrder> zgoList = zhGascardOrderService.selectZhGascardOrderByObj(zgo);
			if(zgoList != null && zgoList.size()>0){
				zgo = zgoList.get(0);
			}
			logger.info("本地订单回调查询："+zgo.getBmItemName()+":"+zgo.getOrderNo());
			model.addAttribute("myOrder", zgo);
			
		}
		
		return "success";
		
	}
	
	/**
	 * 微信推送消息查看充值状态
	 * @param orderNo
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/oil/card/rechargeResult",method=RequestMethod.GET)
	public String showRechargeResult(String orderNo,Model model){
		
		if(StringUtils.isNotEmpty(orderNo)){
			ZhGascardOrder order = zhGascardOrderService.selectZhGascardOrderByOrderNo(orderNo);
			
			if(order != null){
				model.addAttribute("Order", order);
			}
		}
		
		return "RechargeResult";
	}
	
	
	
	
	
}
